package com.xu.cloud.common.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 分片工具类
 *
 * @author xuguan
 * @since 2024/3/9
 */
public class ShardingUtil {

    /**
     * 按照分片数量对集合分片
     *
     * @param totalList     原集合
     * @param shardingCount 分片数量
     * @param <E>           集合元素类型
     * @return 分片集合的集合
     */
    public static <E> List<List<E>> shardingByShardingCount(List<E> totalList, int shardingCount) {
        if (Objects.isNull(totalList) || totalList.isEmpty()) {
            return new ArrayList<>();
        }

        int totalSize = totalList.size();
        int shardingSize = totalSize / shardingCount;

        return doSharding(totalList, shardingSize, shardingCount);
    }

    /**
     * 按照分片大小对集合分片
     *
     * @param totalList    原集合
     * @param shardingSize 分片大小
     * @param <E>          集合元素类型
     * @return 分片集合的集合
     */
    public static <E> List<List<E>> shardingByShardingSize(List<E> totalList, int shardingSize) {
        if (Objects.isNull(totalList) || totalList.isEmpty()) {
            return new ArrayList<>();
        }

        int totalSize = totalList.size();
        int shardingCount = totalSize / shardingSize;
        if (totalSize % shardingSize > 0) {
            shardingCount++;
        }

        return doSharding(totalList, shardingSize, shardingCount);
    }

    private static <E> List<List<E>> doSharding(List<E> totalList, int shardingSize, int shardingCount) {
        final List<List<E>> result = new ArrayList<>(shardingCount);
        for (int i = 0; i < shardingCount; i++) {
            int fromIndex = i * shardingSize;
            int toIndex = (i + 1) * shardingSize;
            // 如果不能整除, 将余数放在最后一个子集合
            if (i == shardingCount - 1) {
                toIndex = totalList.size();
            }
            final List<E> subList = totalList.subList(fromIndex, toIndex);
            result.add(subList);
        }
        return result;
    }
}
